package edu.uwm.RobberKnight.View;

import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

import java.awt.Component;
import javax.swing.JButton;
import javax.swing.border.BevelBorder;
import javax.swing.JScrollPane;
import javax.swing.JList;

import edu.uwm.RobberKnight.Controller.RobberKnightsController;
import edu.uwm.RobberKnight.Model.Player;
import edu.uwm.RobberKnight.Model.Tile;


import java.awt.BorderLayout;
import java.util.LinkedList;
import java.util.List;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ScrollPaneConstants;
import java.awt.Font;

/*
 * A panel that contains key gameplay information.
 */
public class StatusPanel extends JPanel {

    private static final long serialVersionUID = 1995300370815348478L;
    private JTable _scores;
    private JList _list;
    private RobberKnightsController _controller;
    private String[] _scoresHeader = new String[]{"Name", "Deck", "Knights", "Score"};
    private HandsView _currentHand;
    private MultiHandsView _allHands;
    private JButton _btnPeek;
    private GameView _game;

    /**
     * Create the panel.
     */
    public StatusPanel(final RobberKnightsController controller, GameView game) {
    	_game = game;
        _controller = controller;
        JButton btnEndTurn = new JButton("End Turn");
        btnEndTurn.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent arg0) {
                if (_controller.nextTurn()) {
                    _btnPeek.setText("Peek");
                }
            }
        });

        JPanel panel = new JPanel();
        panel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));

        JScrollPane scrollPane = new JScrollPane();

        _btnPeek = new JButton("Peek");
        _btnPeek.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (_currentHand.getShowFaces()) {
                    _btnPeek.setText("Peek");
                    _currentHand.setShowFaces(false);
                } else {
                    _btnPeek.setText("Hide");
                    _currentHand.setShowFaces(true);
                }

            }
        });

        _list = new JList();
        _list.setFont(new Font("Arial", Font.PLAIN, 11));
        _list.setBackground(Color.black);
        _list.setForeground(Color.GRAY);
        JScrollPane ps = new JScrollPane();
        ps.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        ps.setViewportView(_list);

        _list.setModel(new DefaultListModel() {

            private static final long serialVersionUID = 7373382849615719036L;
            String[] lines = controller.getLogs();

            public int getSize() {
                return lines.length;
            }

            public Object getElementAt(int index) {
                return lines[(lines.length - index - 1)];
            }
        });


        JLabel lblHistory = new JLabel("History:");

        JPanel pblHands = new JPanel();
        pblHands.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));

        JLabel lblHands = new JLabel("Hands:");
        GroupLayout groupLayout = new GroupLayout(this);
        groupLayout.setHorizontalGroup(
                groupLayout.createParallelGroup(Alignment.TRAILING).addGroup(groupLayout.createSequentialGroup().addGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(groupLayout.createSequentialGroup().addContainerGap().addGroup(groupLayout.createParallelGroup(Alignment.LEADING).addComponent(pblHands, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE).addComponent(scrollPane, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE).addComponent(lblHands).addComponent(lblHistory).addComponent(ps, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE).addComponent(panel, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE))).addGroup(groupLayout.createSequentialGroup().addGap(113).addComponent(_btnPeek)).addGroup(groupLayout.createSequentialGroup().addGap(103).addComponent(btnEndTurn))).addContainerGap()));
        groupLayout.setVerticalGroup(
                groupLayout.createParallelGroup(Alignment.LEADING).addGroup(groupLayout.createSequentialGroup().addContainerGap().addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE).addPreferredGap(ComponentPlacement.RELATED).addComponent(lblHands).addPreferredGap(ComponentPlacement.RELATED).addComponent(pblHands, GroupLayout.PREFERRED_SIZE, 104, GroupLayout.PREFERRED_SIZE).addPreferredGap(ComponentPlacement.RELATED).addComponent(lblHistory).addPreferredGap(ComponentPlacement.RELATED).addComponent(ps, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE).addPreferredGap(ComponentPlacement.RELATED).addComponent(_btnPeek).addPreferredGap(ComponentPlacement.RELATED).addComponent(panel, GroupLayout.PREFERRED_SIZE, 95, GroupLayout.PREFERRED_SIZE).addPreferredGap(ComponentPlacement.RELATED).addComponent(btnEndTurn).addContainerGap(107, Short.MAX_VALUE)));
        panel.setLayout(new BorderLayout(0, 0));

        _currentHand = new HandsView(_controller, this);
        panel.add(_currentHand);
        pblHands.setLayout(new BorderLayout(0, 0));

        _allHands = new MultiHandsView(_controller);
        pblHands.add(_allHands);

        _scores = new JTable() {

            private static final long serialVersionUID = 6407069228607703049L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component comp = super.prepareRenderer(renderer, row, column);
                comp.setBackground(Color.BLACK);
                List<Player> plist = _controller.getPlayers();
                switch (row) {
                    case 0:
                        if (plist != null && plist.size() >= 1) {
                            comp.setForeground(plist.get(0).getColor());
                            if (plist.get(0).equals(_controller.getCurrentPlayer())) {
                                comp.setBackground(Color.LIGHT_GRAY);
                            }

                        }
                        break;
                    case 1:
                        if (plist != null && plist.size() >= 2) {
                            comp.setForeground(plist.get(1).getColor());
                            if (plist.get(1).equals(_controller.getCurrentPlayer())) {
                                comp.setBackground(Color.LIGHT_GRAY);
                            }
                        }
                        break;
                    case 2:
                        if (plist != null && plist.size() >= 3) {
                            comp.setForeground(plist.get(2).getColor());
                            if (plist.get(2).equals(_controller.getCurrentPlayer())) {
                                comp.setBackground(Color.LIGHT_GRAY);
                            }
                        }
                        break;
                    case 3:
                        if (plist != null && plist.size() >= 4) {
                            comp.setForeground(plist.get(3).getColor());
                            if (plist.get(3).equals(_controller.getCurrentPlayer())) {
                                comp.setBackground(Color.LIGHT_GRAY);
                            }
                        }
                        break;
                }
                return comp;
            }
        };
        _scores.setForeground(Color.WHITE);
        _scores.setShowGrid(false);
        _scores.setEnabled(false);
        _scores.setModel(new DefaultTableModel(
                new Object[][]{
                    {"", "", "", ""},
                    {"", "", "", ""},
                    {"", "", "", ""},
                    {"", "", "", ""},},
                _scoresHeader));
        scrollPane.setViewportView(_scores);
        _scores.setShowVerticalLines(false);
        _scores.setShowHorizontalLines(false);
        _scores.setRowSelectionAllowed(false);
        _scores.setFillsViewportHeight(true);
        _scores.setBackground(Color.BLACK);
        setLayout(groupLayout);
    }

    /*
     * Make sure the child controls are all up to date and displaying the correct information.
     */
    public void updateState(long time) {
        _currentHand.updateState(time);
        _allHands.updateState(time);
        TableModel model = _scores.getModel();
        LinkedList<Player> players = _controller.getPlayers();
        if (players != null) {
            for (int i = 0; i < players.size(); i++) {
                Player player = players.get(i);
                char letter = player.getTopTileChar();
                model.setValueAt(player.getName(), i, 0);
                model.setValueAt(letter + " " + player.getTilesSize(), i, 1);
                model.setValueAt(player.getKnightsSize(), i, 2);
                model.setValueAt(player.getScore(), i, 3);

            }
            //rest of the table should be cleared
            for(int i = players.size(); i < 4; i++) {
            	model.setValueAt("", i, 0);
            	model.setValueAt("", i, 1);
            	model.setValueAt("", i, 2);
            	model.setValueAt("", i, 3);
            }
        }
        _list.setModel(new DefaultListModel() {

            private static final long serialVersionUID = -3418436667814758390L;
            String[] lines = _controller.getLogs();

            public int getSize() {
                return lines.length;
            }

            public Object getElementAt(int index) {
                return lines[lines.length - index - 1];
            }
        });

    }
    
    /*
     * Set the tile information display to the specified tile.
     */
    public void setDisplayTile(Tile tile) {
    	_game.setDisplayTile(tile);
    }
}
